Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(connector): [Paypal] Add support for passing shipping_cost in Payment request #6423

Merged
merged 8 commits into from
Oct 25, 2024

Conversation

swangi-kumari
Copy link
Contributor

@swangi-kumari swangi-kumari commented Oct 24, 2024

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

  • Add support for passing shipping_cost in Payment request of Paypal
  • In paypal we can pass shipping_cost while creating payment_intent, I have added this in the flows PaymentsAuthorizeRouterData, PaymentsPostSessionTokensRouterData and SdkSessionUpdateRouterData

Additional Changes

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

  1. Create Merchant Account
curl --location 'http://localhost:8080/accounts' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data-raw '{
  "merchant_id": "merchant_1728546485",
  "locker_id": "m0010",
  "merchant_name": "NewAge Retailer",
  "merchant_details": {
    "primary_contact_person": "John Test",
    "primary_email": "JohnTest@test.com",
    "primary_phone": "sunt laborum",
    "secondary_contact_person": "John Test2",
    "secondary_email": "JohnTest2@test.com",
    "secondary_phone": "cillum do dolor id",
    "website": "https://www.example.com",
    "about_business": "Online Retail with a wide selection of organic products for North America",
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US"
    }
  },
  "return_url": "https://google.com/success",
  "webhook_details": {
    "webhook_version": "1.0.1",
    "webhook_username": "ekart_retail",
    "webhook_password": "password_ekart@123",
    "payment_created_enabled": true,
    "payment_succeeded_enabled": true,
    "payment_failed_enabled": true
  },
  "sub_merchants_enabled": false,
  "metadata": {
    "city": "NY",
    "unit": "245"
  },
  "primary_business_details": [
    {
      "country": "US",
      "business": "food"
    }
  ]
}'
  1. Create API Key
curl --location 'http://localhost:8080/api_keys/merchant_1728540504' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
  "name": "API Key 1",
  "description": null,
  "expiration": "2025-09-23T01:02:03.000Z"
}'
  1. Create MCA of Paypal
curl --location 'http://localhost:8080/account/merchant_1728540504/connectors?=' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "paypal",
    "connector_account_details": {
        "auth_type": "BodyKey",
        "api_key": "_",
        "key1": "_"
    },
    "test_mode": false,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "paypal",
                    "payment_experience": "redirect_to_url",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": false,
                    "installment_payment_enabled": false
                },
                {
                    "payment_method_type": "paypal",
                    "payment_experience": "invoke_sdk_client",
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": false,
                    "installment_payment_enabled": false
                }
                
            ]
        },
        {
            "payment_method": "bank_redirect",
            "payment_method_types": [
                {
                    "payment_method_type": "giropay",
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "payment_experience": "redirect_to_url"
                },
                {
                    "payment_method_type": "ideal",
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "payment_experience": "redirect_to_url"
                },
                {
                    "payment_method_type": "eps",
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "payment_experience": "redirect_to_url"
                },
                {
                    "payment_method_type": "sofort",
                    "recurring_enabled": true,
                    "installment_payment_enabled": true,
                    "payment_experience": "redirect_to_url"
                }
            ]
        }
    ],
     "metadata": {
        "paypal_sdk": {
            "client_id": "___"
        }
    },
    "business_country": "US",
    "business_label": "food"
}'
  1. Create MCA of Taxjar
curl --location 'http://localhost:8080/account/merchant_1729762835/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "connector_type": "tax_processor",
    "connector_name": "taxjar",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "_" 
    },

    "test_mode": false,
    "disabled": false,

    "metadata": {
        "city": "NY",
        "unit": "245"
    },

    "business_country": "US",
    "business_label": "food"
}'
  1. Create payment and pass shipping_cost in request
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_QdrlaR3PrAy4lCuB723Rs9gwDzJipYiEsSkHO5WCC9ZmjCLUcPA3okUdN3CggBfg' \
--data-raw '{
    "amount": 2500,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "StripeCustomer",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "shipping_cost": 1000,
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "swangi@gmail.com"
    },
    "order_details": [ 
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 1000,
            "product_tax_code": "23"
        },
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 1500,            
                    "product_tax_code": "23"
        }
    ],
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
    
}'
  1. Create Session token
curl --location 'http://localhost:8080/payments/session_tokens' \
--header 'Content-Type: application/json' \
--header 'api-key: pk_dev_10cfee22267a4184a3d45665920788ea' \
--data '{
    "payment_id": "pay_J3IXGvol8nNvUkSRTcwQ",
    "wallets": [],
    "client_secret": "pay_J3IXGvol8nNvUkSRTcwQ_secret_VN76rK4oCqTghQ1kwNcO"
}'

Response

{
    "payment_id": "pay_mcVzUMZws5KmEKbGkZ0g",
    "client_secret": "pay_mcVzUMZws5KmEKbGkZ0g_secret_RMWlmy1jSdlp9VOMX1qc",
    "session_token": [
        {
            "wallet_name": "paypal",
            "connector": "paypal",
            "session_token": "ASKAGh2WXgqfQ5TzjpZzLsfhVGlFbjq5VrV5IOX8KXDD2N_XqkGeYNDkWyr_UXnfhXpEkABdmP284b_2",
            "sdk_next_action": {
                "next_action": "post_session_tokens"
            }
        }
    ]
}
  1. List Payment Methods for merchant - Check for required fields (shipping_details)
curl --location 'http://localhost:8080/account/payment_methods?client_secret=pay_J3IXGvol8nNvUkSRTcwQ_secret_VN76rK4oCqTghQ1kwNcO' \
--header 'Accept: application/json' \
--header 'api-key: pk_dev_10cfee22267a4184a3d45665920788ea'

Response

{
    "redirect_url": "https://google.com/success",
    "currency": "USD",
    "payment_methods": [
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "paypal",
                    "payment_experience": [
                        {
                            "payment_experience_type": "invoke_sdk_client",
                            "eligible_connectors": [
                                "paypal"
                            ]
                        },
                        {
                            "payment_experience_type": "redirect_to_url",
                            "eligible_connectors": [
                                "paypal"
                            ]
                        }
                    ],
                    "card_networks": null,
                    "bank_names": null,
                    "bank_debits": null,
                    "bank_transfers": null,
                    "required_fields": {
                        "shipping.address.country": {
                            "required_field": "shipping.address.country",
                            "display_name": "country",
                            "field_type": {
                                "user_shipping_address_country": {
                                    "options": [
                                        "ALL"
                                    ]
                                }
                            },
                            "value": "US"
                        },
                        "shipping.address.first_name": {
                            "required_field": "shipping.address.first_name",
                            "display_name": "shipping_first_name",
                            "field_type": "user_shipping_name",
                            "value": "PiX"
                        },
                        "shipping.address.zip": {
                            "required_field": "shipping.address.zip",
                            "display_name": "zip",
                            "field_type": "user_shipping_address_pincode",
                            "value": "94122"
                        },
                        "shipping.address.state": {
                            "required_field": "shipping.address.state",
                            "display_name": "state",
                            "field_type": "user_shipping_address_state",
                            "value": "California"
                        },
                        "shipping.address.city": {
                            "required_field": "shipping.address.city",
                            "display_name": "city",
                            "field_type": "user_shipping_address_city",
                            "value": "San Fransico"
                        },
                        "shipping.address.last_name": {
                            "required_field": "shipping.address.last_name",
                            "display_name": "shipping_last_name",
                            "field_type": "user_shipping_name",
                            "value": null
                        },
                        "shipping.address.line1": {
                            "required_field": "shipping.address.line1",
                            "display_name": "line1",
                            "field_type": "user_shipping_address_line1",
                            "value": "1467"
                        }
                    },
                    "surcharge_details": null,
                    "pm_auth_connector": null
                }
            ]
        },
            ],
    "mandate_payment": null,
    "merchant_name": "NewAge Retailer",
    "show_surcharge_breakup_screen": false,
    "payment_type": "normal",
    "request_external_three_ds_authentication": false,
    "collect_shipping_details_from_wallets": false,
    "collect_billing_details_from_wallets": false,
    "is_tax_calculation_enabled": false
}
  1. Create Post Session Tokens for Paypal
curl --location 'http://localhost:8080/payments/pay_J3IXGvol8nNvUkSRTcwQ/post_session_tokens' \
--header 'Content-Type: application/json' \
--header 'api-key: pk_dev_10cfee22267a4184a3d45665920788ea' \
--data '{
    "client_secret": "pay_J3IXGvol8nNvUkSRTcwQ_secret_VN76rK4oCqTghQ1kwNcO",
    "payment_method_type": "paypal",
    "payment_method": "wallet"
}'

Response

 {
    "payment_id": "pay_mcVzUMZws5KmEKbGkZ0g",
    "next_action": {
        "type": "invoke_sdk_client",
        "next_action_data": {
            "next_action": "confirm",
            "order_id": "2KW93090954330301"
        }
    }
}
  1. Call /calculate_tax - SessionUpdate
curl --location 'http://localhost:8080/payments/pay_mcVzUMZws5KmEKbGkZ0g/calculate_tax' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: pk_dev_43922dfcb2694e09929891b0f4f7b6dc' \
--data-raw '{
    
    "client_secret": "_",
 
    "shipping": {
        "address": {
            "line1": "1335",
            "line2": "E 103rd St",
            
            "city": "Los Angeles",
            "state": "California",
            "zip": "90002",
            "country": "US",
            "first_name": "Test",
            "last_name": "Person-us"
        },
        "phone": {
            "number": "5551234",
            "country_code": "+1"
        },
        "email": "generated_email_us+1715685671426@example.com"
    },
    "payment_method_type": "paypal"

}
'

Response

{
    "payment_id": "pay_QTMdIrjFCvQTauCQWo10",
    "net_amount": 3719,
    "order_tax_amount": 219,
    "shipping_cost": 1000,
    "display_amount": {
        "net_amount": "37.19",
        "order_tax_amount": "2.19",
        "shipping_cost": "10.00"
    }
}
  1. Confirm Request
curl 'http://localhost:8080/payments/pay_6oSZ2utmkjgdOlfrZ53E/confirm' \
-X 'POST' \
-H 'Content-Type: application/json' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Sec-Fetch-Mode: cors' \
-H 'x-payment-confirm-source: sdk' \
-H 'x-client-source: ExpressCheckoutElement' \
-H 'api-key: pk_dev_43922dfcb2694e09929891b0f4f7b6dc' \
-H 'x-browser-version: 605.1.15' \
--data-binary '{"client_secret":"________","return_url":"http://localhost:9060","retry_action":"manual_retry","shipping":{"address":{"country":"US","state":"California","zip":"94588","first_name":"Jagan","city":"Pleasanton","last_name":"Elavarasan","line1":"4141"}},"payment_method":"wallet","payment_method_type":"paypal","payment_experience":"invoke_sdk_client","connector":["paypal"],"payment_method_data":{"wallet":{"paypal_sdk":{"token":""}}},"browser_info":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1.2 Safari/605.1.15","accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","language":"en-US","color_depth":24,"screen_height":1117,"screen_width":1728,"time_zone":-330,"java_enabled":true,"java_script_enabled":true},"payment_type":"normal"}'

Response

    "payment_id": "pay_QTMdIrjFCvQTauCQWo10",
    "merchant_id": "merchant_1729762835",
    "status": "succeeded",
    "amount": 2500,
    "net_amount": 3719,
    "shipping_cost": 1000,
    "amount_capturable": 0,
    "amount_received": 3719,
    "connector": "paypal",
    "client_secret": "pay_QTMdIrjFCvQTauCQWo10_secret_cgBLJ8VK5WFUUZvQhnwJ",
    "created": "2024-10-24T09:54:03.238Z",
    "currency": "USD",
    "customer_id": "hyperswitch_sdk_demo_id",
    "customer": {
        "id": "hyperswitch_sdk_demo_id",
        "name": null,
        "email": "hyperswitch_sdk_demo_id@gmail.com",
        "phone": null,
        "phone_country_code": null
    },
    "description": "Hello this is description",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "wallet",
    "payment_method_data": {
        "wallet": {},
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "Pleasanton",
            "country": "US",
            "line1": "4141",
            "line2": "Amsterdam Ave",
            "line3": "alsksoe",
            "zip": "94588",
            "state": "California",
            "first_name": "Jagan",
            "last_name": "Elavarasan"
        },
        "phone": {
            "number": "9876540321",
            "country_code": "+1"
        },
        "email": "jagan.elavarasan@juspay.in"
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": "swangi@getMaxListeners.com"
    },
    "order_details": [
        {
            "brand": null,
            "amount": 1500,
            "category": null,
            "quantity": 1,
            "product_id": null,
            "product_name": "Apple iPhone 15",
            "product_type": null,
            "sub_category": null,
            "product_img_link": null,
            "product_tax_code": null,
            "requires_shipping": null
        },
        {
            "brand": null,
            "amount": 1000,
            "category": null,
            "quantity": 1,
            "product_id": null,
            "product_name": "Apple iPhone 16",
            "product_type": null,
            "sub_category": null,
            "product_img_link": null,
            "product_tax_code": null,
            "requires_shipping": null
        }
    ],
    "email": "hyperswitch_sdk_demo_id@gmail.com",
    "name": null,
    "phone": null,
    "return_url": "http://localhost:9060/",
    "authentication_type": "three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": "invoke_sdk_client",
    "payment_method_type": "paypal",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": false,
    "connector_transaction_id": "59Y22595XY359373P",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_QTMdIrjFCvQTauCQWo10_1",
    "payment_link": null,
    "profile_id": "pro_bFxSMR1bdhJsyq2t9WmR",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_oS1q9hdrFTXOBSCMjzp4",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-10-24T10:09:03.238Z",
    "fingerprint": null,
    "browser_info": {
        "language": "en-US",
        "time_zone": -330,
        "ip_address": "::1",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1.2 Safari/605.1.15",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1728,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 1117,
        "java_script_enabled": true
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-10-24T09:54:38.047Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": 219,
    "connector_mandate_id": null
}

Checklist

  • I formatted the code cargo +nightly fmt --all
  • I addressed lints thrown by cargo clippy
  • I reviewed the submitted code
  • I added unit tests for my changes where possible

@swangi-kumari swangi-kumari added A-connector-integration Area: Connector integration C-refactor Category: Refactor labels Oct 24, 2024
@swangi-kumari swangi-kumari self-assigned this Oct 24, 2024
@swangi-kumari swangi-kumari requested review from a team as code owners October 24, 2024 08:37
Copy link

semanticdiff-com bot commented Oct 24, 2024

Review changes with SemanticDiff.

Analyzed 7 of 7 files.

Overall, the semantic diff is 33% smaller than the GitHub diff.

Filename Status
✔️ crates/router/tests/connectors/utils.rs Analyzed
✔️ crates/router/src/types.rs Analyzed
✔️ crates/router/src/types/api/verify_connector.rs Analyzed
✔️ crates/router/src/core/payments/transformers.rs 0.44% smaller
✔️ crates/router/src/connector/paypal.rs 39.17% smaller
✔️ crates/router/src/connector/paypal/transformers.rs 37.92% smaller
✔️ crates/hyperswitch_domain_models/src/router_request_types.rs 15.27% smaller

@@ -863,6 +863,7 @@ impl ForeignFrom<&SetupMandateRouterData> for PaymentsAuthorizeData {
charges: None, // TODO: allow charges on mandates?
merchant_order_reference_id: None,
integrity_object: None,
shipping_cost: None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should send the shipping_cost here

Copy link
Contributor

@apoorvdixit88 apoorvdixit88 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine for dashboard changes.

@likhinbopanna likhinbopanna added this pull request to the merge queue Oct 25, 2024
Merged via the queue into main with commit b0d5c96 Oct 25, 2024
17 checks passed
@likhinbopanna likhinbopanna deleted the paypal-shipping branch October 25, 2024 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-connector-integration Area: Connector integration C-refactor Category: Refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants